﻿using System;

namespace Microsoft.Popfly.GameCreator.GameEngine.Behaviors
{
    public class SimpleXVelocityMove : XMoveBehavior
	{
    	public SimpleXVelocityMove(BehaviorOwner owner, double velocity) : base(owner, velocity){}

		public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
		{
			m_owner.XVelocity += m_offset;
		}
    }

    public class SimpleYVelocityMove : YMoveBehavior
	{
		public SimpleYVelocityMove(BehaviorOwner owner, double velocity) : base(owner, velocity) {}

		#region Behavior Members

		public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
		{
			m_owner.YVelocity += m_offset;
		}

		#endregion
	}

    public class SimpleXYVelocityMove : XYMoveBehavior
	{
		private double m_XVelocity;
		private double m_YVelocity;

		private static double sqrtOfTwoOverTwo = Math.Sqrt(2) / 2.0;

		public SimpleXYVelocityMove(BehaviorOwner owner, double velocityMagnitude, Data.MotionInfo.DirectionValues direction) : base(owner, velocityMagnitude)
		{
			switch (direction)
			{
				case Data.MotionInfo.DirectionValues.NE:
					m_XVelocity = sqrtOfTwoOverTwo;
					m_YVelocity = -sqrtOfTwoOverTwo;
					break;
				case Data.MotionInfo.DirectionValues.NW:
					m_XVelocity = -sqrtOfTwoOverTwo;
					m_YVelocity = -sqrtOfTwoOverTwo;
					break;
				case Data.MotionInfo.DirectionValues.SE:
					m_XVelocity = sqrtOfTwoOverTwo;
					m_YVelocity = sqrtOfTwoOverTwo;
					break;
				case Data.MotionInfo.DirectionValues.SW:
					m_XVelocity = -sqrtOfTwoOverTwo;
					m_YVelocity = sqrtOfTwoOverTwo;
					break;
				default:
					throw new ArgumentException(
						Utils.ErrorMessagePrefix + "SimpleXYMove is only for direction values of NE, NW, SE or SW.  '" +
						direction.ToString() + "' was passed in instead.");
			}

            m_XVelocity *= velocityMagnitude;
            m_YVelocity *= velocityMagnitude;
		}

		#region Behavior Members

		public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
		{
            if (m_isOriginalDirection)
            {
                m_owner.YVelocity += m_YVelocity;
                m_owner.XVelocity += m_XVelocity;
            }
            else
            {
                m_owner.YVelocity -= m_YVelocity;
                m_owner.XVelocity -= m_XVelocity;
            }
			
		}

		#endregion
    }

    public class SimpleVelocityRotation : RotateBehavior
	{
		private Actor m_actorOwner;
        
        public SimpleVelocityRotation(Actor owner, double velocity) : base(owner, velocity)
		{
			m_actorOwner = owner;
		}

		public SimpleVelocityRotation(BehaviorOwner owner, Data.MotionInfo rotationInfo) : base(owner, rotationInfo.VelocityJump)
		{
            if (owner.GetType() != typeof(Actor))
            {
                throw new ArgumentException(
                    Utils.ErrorMessagePrefix +
                    "Rotation behaviors only apply to Actors, but one is being created for a '" +
                    owner.GetType().ToString() +
                    "'."
                    );
            }
            m_actorOwner = (Actor) owner;
			if (rotationInfo.Relative != Data.MotionInfo.RelativeValues.Self)
			{
				throw new ArgumentException(
					Utils.ErrorMessagePrefix +
					"SimpleRotation only knows how to handle clockwise/counterclockwise motions relative to self.  '"
					+ rotationInfo.Relative.ToString() + "' was passed in."
						);
			}

			switch (rotationInfo.Direction)
			{
				case Data.MotionInfo.DirectionValues.E:
					m_offset = -rotationInfo.VelocityJump;
					break;
				case Data.MotionInfo.DirectionValues.W:
					m_offset = rotationInfo.VelocityJump;
					break;
				default:
					throw new ArgumentException(
						Utils.ErrorMessagePrefix +
						"SimpleRotation only understands E for counter clockwise and W for clockwise.  '" +
						rotationInfo.Direction.ToString() + "' was passed in."
						);
			}
		}

        public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
		{
			m_actorOwner.RotationVelocity += m_offset;
		}
    }
}
